/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package dnbW.queryW.visualW;

import java.util.Enumeration;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

/**
 *
 * @author zhouyong
 */
public class ConditionTree extends DefaultTreeModel{
    
    private OperatorVertex conditionRoot;
    private boolean isMovingNode = false;
    
    public ConditionTree(OperatorVertex root){
        super(root);
        this.conditionRoot = root;
    }
    
    private void addNode(PredicateVertex node, PredicateVertex parent) {
        if (parent == null) {
            parent = conditionRoot;
        }
        parent.add(node);
        int index = parent.getIndex(node);
        super.nodesWereInserted(parent, new int[]{index});
    }
    
    public void updateVertex(PredicateVertex newVertex){
        if(conditionRoot.isNodeDescendant(newVertex))
            super.nodeChanged(newVertex);
    }
    
    public void deleteNode(PredicateVertex node, boolean retainChildren){
        if(node == conditionRoot)
            return;
        
        if(node.isLeaf()){
            TreeNode parent = node.getParent();
            int index = parent.getIndex(node);
            node.removeFromParent();
            super.nodesWereRemoved(parent, new int[]{index}, new Object[]{node});
        }else{
            PredicateVertex parent = (PredicateVertex) node.getParent();
            if(retainChildren){
                for(Enumeration em = node.children(); em.hasMoreElements(); ){
                    moveNode((PredicateVertex)em.nextElement(), parent);
                }
            }else{
                for(Enumeration em = node.children(); em.hasMoreElements(); ){
                    deleteNode((PredicateVertex)em.nextElement(), false);
                }
            }
            deleteNode(node, retainChildren);
        }
    }
    
    public void moveNode(PredicateVertex node, PredicateVertex target){
        if(node == conditionRoot)
            return;
        
        if(target instanceof JoinVertex)
            return;
        
        if(!(target instanceof OperatorVertex))
            return;
        
        if(target.isNodeChild(node))
            return;
        
        // set isMovingNode parameter to true
        // user must check isMoveingNode() 
        TreeNode parent = node.getParent();
        int index = parent.getIndex(node);
        node.removeFromParent();
        
        isMovingNode = true;
        nodesWereRemoved(parent, new int[]{index}, new Object[]{node});
        addNode(node, target);
        isMovingNode = false;
    }
    
    public void addComparisonVertex(ComparisonVertex cv, OperatorVertex parent){
        if(parent == null)
            parent = this.conditionRoot;
        
        this.addNode(cv, parent);
    }
    
    public void addJoinVertex(JoinVertex jv, OperatorVertex parent) {
        if (parent == null) {
            parent = this.conditionRoot;
        }
        addNode(jv, parent);
    }
    
    public void addOperatorVertex(OperatorVertex op, OperatorVertex parent) {
        if (parent == null) {
            parent = this.conditionRoot;
        }
        addNode(op, parent);
    }

    public boolean isMovingNode() {
        return isMovingNode;
    }

    public OperatorVertex getConditionRoot() {
        return conditionRoot;
    }

}
